
#include "ProductsModelDelegate.h"
#include "ProductsModel.h"

#include <QDoubleSpinBox>
#include <QComboBox>

using namespace ecocity;

ProductsModelDelegate::ProductsModelDelegate( const std::vector< Proveider >& proveiders,
                                              QObject *parent )
        : QItemDelegate( parent ),
          m_proveiders( proveiders )
{
}

//---------------------------------------------------------------

void
ProductsModelDelegate::paint( QPainter *painter,
                              const QStyleOptionViewItem &option,
                              const QModelIndex &index ) const
{
    QStyleOptionViewItem my_option = option;
    my_option.displayAlignment = Qt::AlignRight | Qt::AlignVCenter;

    QString text;

    switch ( index.column( ) )
    {
    case ProductsModel::PRODUCT_COST_ECOCITY:
    case ProductsModel::PRODUCT_PRICE_COOPE:
    case ProductsModel::PRODUCT_PRICE_SHOP:
    case ProductsModel::PRODUCT_PRICE_END_CUSTOMER:
    {
        text = decorate_price_index( index );
        break;
    }
    case ProductsModel::PRODUCT_TAX_RATE:
    case ProductsModel::PRODUCT_PROFIT_RATE:
    {
        int price = index.model()->data( index, Qt::DisplayRole ).toInt();
        text = QString::number( price );
        text.append( QString::fromUtf8( " %" ) );
        break;
    }
    default:
        QItemDelegate::paint( painter, option, index );
        return; // return is fine here
    }

    drawDisplay( painter, my_option, my_option.rect, text );
    drawFocus( painter, my_option, my_option.rect );
}

//---------------------------------------------------------------

QWidget*
ProductsModelDelegate::createEditor( QWidget *parent, const QStyleOptionViewItem &option,
                                     const QModelIndex &index) const
{
    switch ( index.column( ) )
    {
    case ProductsModel::PRODUCT_COST_ECOCITY:
    case ProductsModel::PRODUCT_PRICE_COOPE:
    case ProductsModel::PRODUCT_PRICE_SHOP:
    case ProductsModel::PRODUCT_PRICE_END_CUSTOMER:
    {
        QDoubleSpinBox* spin_box = new QDoubleSpinBox( parent );
        spin_box->setDecimals( 2 );
        connect( spin_box, SIGNAL( editingFinished( ) ),
                 this, SLOT( commitAndCloseSpinBox( ) ) );

        return spin_box;
    }
    case ProductsModel::PRODUCT_PRICE_TYPE:
    {
        QComboBox *combo_box = new QComboBox( parent );

        combo_box->addItem( "POR_UNIDAD" );
        combo_box->addItem( "POR_KILO" );

        connect( combo_box, SIGNAL( editingFinished( ) ),
                 this, SLOT( commitAndCloseComboBox( ) ) );

        return combo_box;
    }
    default:
        return QItemDelegate::createEditor( parent, option, index );
    }
}

//---------------------------------------------------------------

void
ProductsModelDelegate::commitAndCloseSpinBox( )
{
    QDoubleSpinBox *editor = qobject_cast<QDoubleSpinBox *>(sender( ));
    emit commitData( editor );
    emit closeEditor( editor );
}

//---------------------------------------------------------------

void
ProductsModelDelegate::commitAndCloseComboBox( )
{
    QComboBox *editor = qobject_cast<QComboBox *>(sender( ));
    emit commitData( editor );
    emit closeEditor( editor );
}

//---------------------------------------------------------------

void
ProductsModelDelegate::setEditorData( QWidget *editor,
                                      const QModelIndex &index ) const
{
    switch ( index.column( ) )
    {
    case ProductsModel::PRODUCT_COST_ECOCITY:
    case ProductsModel::PRODUCT_PRICE_COOPE:
    case ProductsModel::PRODUCT_PRICE_SHOP:
    case ProductsModel::PRODUCT_PRICE_END_CUSTOMER:
    {
        float price = index.model()->data( index, Qt::DisplayRole).toFloat( );
        QDoubleSpinBox *price_edit = qobject_cast<QDoubleSpinBox *>(editor);
        price_edit->setValue( price );
        break;
    }
    case ProductsModel::PRODUCT_PRICE_TYPE:
    {
        const QString price_type = index.model()->data( index, Qt::DisplayRole ).toString( );
        QComboBox* price_type_edit = qobject_cast<QComboBox *>(editor);

        int combo_index = price_type_edit->findText( price_type );
        price_type_edit->setCurrentIndex( combo_index );
        break;
    }
    default:
        QItemDelegate::setEditorData( editor, index );
        break;
    }
}

//---------------------------------------------------------------

void
ProductsModelDelegate::setModelData( QWidget *editor,
                                     QAbstractItemModel *model,
                                     const QModelIndex &index) const
{
    switch ( index.column( ) )
    {
    case ProductsModel::PRODUCT_COST_ECOCITY:
    case ProductsModel::PRODUCT_PRICE_COOPE:
    case ProductsModel::PRODUCT_PRICE_SHOP:
    case ProductsModel::PRODUCT_PRICE_END_CUSTOMER:
    {
        QDoubleSpinBox *price_edit = qobject_cast<QDoubleSpinBox *>(editor);
        float price = price_edit->value( );
        model->setData( index, price );
        emit price_changed( model, index, price );
        break;
    }
    case ProductsModel::PRODUCT_PRICE_TYPE:
    {
        QComboBox *price_type_edit = qobject_cast<QComboBox *>(editor);
        const QString price_type = price_type_edit->currentText( );
        model->setData( index, price_type );
        emit index_price_type_changed( model, index, price_type );
        break;
    }
    default:
        QItemDelegate::setModelData( editor, model, index );
        break;
    }
}

//---------------------------------------------------------------

QString
ProductsModelDelegate::decorate_price_index( const QModelIndex& price_index ) const
{
    QString text;

    float price = price_index.model()->data( price_index, Qt::DisplayRole ).toFloat( );
    text = QString::number( price, 'f', 2 );

    const QAbstractItemModel* model = price_index.model( );

    const QModelIndex index_price_type =
            model->index( price_index.row( ), ProductsModel::PRODUCT_PRICE_TYPE );

    const QString price_type_str = index_price_type.data( ).toString( );

    Product::PRICE_TYPE price_type =
            Product::to_price_type( price_type_str );

    switch ( price_type )
    {
    case Product::PER_KILO:
    {
        text.append( QString::fromUtf8( " €/Kilo" ) );
        break;
    }
    case Product::PER_UNIT:
    {
        text.append( QString::fromUtf8( " €/Uni." ) );
        break;
    }
    default:
        break;
    }

    return text;
}
